﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Workflow.Activities;
using Microsoft.Crm.Workflow;
using System.Workflow.ComponentModel;
using Microsoft.Crm.Sdk;
using System.Diagnostics;

namespace Infusion.CRM.WF.CRM40ShareStep
{

    /// <summary>
    /// Custom base class for all Sequence Activities.
    /// </summary>
    public abstract class SequenceActivityBase : SequenceActivity
    {

        public const string RESULT_FAILURE = "Failure";
        public const string RESULT_SUCCESS = "Success";
        public const string OPERATION_DELETE = "Delete";

        /// <summary>
        /// We cannot serialize SequenceActivity if they have member variables, so we use this class to maintain status
        /// </summary>
        public class Context
        {

            #region Properties

            /// <summary>
            /// Execution context (received from CRM).
            /// </summary>
            public IWorkflowContext WFContext { get; set; }

            /// <summary>
            /// Primary Key of the entity the WF runs on.
            /// </summary>
            public Guid CurrentRecordId { get; set; }

            /// <summary>
            /// Name of the entity the WF runs on.
            /// </summary>
            public string CurrentEntityName { get; set; }

            /// <summary>
            /// Operation that triggered the workflow.
            /// </summary>
            public string CurrentOperation { get; set; }

            /// <summary>
            /// CRM Web Service.
            /// </summary>
            public ICrmService SvcHandle;

            #endregion

        }

        #region Workflow Properties

        /// <summary>
        /// Custom parameter returned to the caller.
        /// </summary>
        public abstract string Result { get; set; }

        #endregion

        #region SequenceActivity

        /// <summary>
        /// Workflow step.
        /// </summary>
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            try
            {
                IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
                Context context = new Context();
                context.WFContext = contextService.Context;

                context.CurrentRecordId = context.WFContext.PrimaryEntityId;
                context.CurrentOperation = context.WFContext.MessageName;
                context.CurrentEntityName = context.WFContext.PrimaryEntityName;
                context.SvcHandle = context.WFContext.CreateCrmService();

                // Execute the actual workflow step body
                this.Result = ExecuteBody(context);
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
                this.Result = RESULT_FAILURE;
            }

            return ActivityExecutionStatus.Closed;
        }

        /// <summary>
        /// Overridden in derived classes: contains the actual workflow step.
        /// </summary>
        /// <returns>Return value will be placed in the Result field of the workflow</returns>
        protected abstract string ExecuteBody(Context context);

        #endregion

    }

}
